package br.com.amps.dao.generic;

import java.io.Serializable;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.NoResultException;
import javax.persistence.Persistence;

public abstract class GenericDAOimpl <T, I extends Serializable> implements GenericDAO<T, I>{

	private EntityManagerFactory factory;
	private EntityManager manager;

	
	public GenericDAOimpl() {
		factory = Persistence.createEntityManagerFactory("K21_mapeamento");
		manager = factory.createEntityManager();
	}
	
	@Override
	public T save(T entity) {
		T saved = null;
		   
		getEntityManager().getTransaction().begin();
		saved = getEntityManager().merge(entity);
		getEntityManager().getTransaction().commit();
		this.closeConnection();
		
		return saved;
	}

	@Override
	public void remove(T entity) {
		getEntityManager().getTransaction().begin();
		getEntityManager().remove(entity);
		getEntityManager().getTransaction().commit();
		this.closeConnection();
	}
	
	@Override
	public void refresh(T entity) {
		getEntityManager().getTransaction().begin();
		getEntityManager().refresh(entity);
		getEntityManager().getTransaction().commit();
		this.closeConnection();
	}

	@Override
	public T getById(Class<T> classe, I pk) {
		try {
			   return getEntityManager().find(classe, pk);
		} catch (NoResultException e) {
			   return null;
		}finally{
			this.closeConnection();
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<T> getAll(Class<T> classe) {
		List<T> t = (List<T>) getEntityManager().createQuery("select o from " + classe.getSimpleName() + " o").getResultList();
		this.closeConnection();
		return t;
	}	
	
	@Override
	public void removeAll(List<T> list) throws Exception {
		getEntityManager().getTransaction().begin();
		try{
			for(T t : list){
				getEntityManager().remove(t);
			}
		}catch(Exception e){
			if(getEntityManager().getTransaction().isActive()){
				getEntityManager().getTransaction().rollback();
			}
		}
		getEntityManager().getTransaction().commit();
		this.closeConnection();
	}
	
	@Override
	public void removeAll(Class<T> t) throws Exception {
		this.removeAll(this.getAll(t));
	}


	protected EntityManager getEntityManager() {
		return manager;
	}
	
	protected void closeConnection(){
		this.manager.close();
		this.factory.close();
	}

}
